using System;
using Tayx.Graphy.Advanced;
using Tayx.Graphy.Audio;
using Tayx.Graphy.Fps;
using Tayx.Graphy.Ram;
using Tayx.Graphy.Utils;
using UnityEngine;

namespace Tayx.Graphy
{
	public class GraphyManager : G_Singleton<GraphyManager>
	{
		public enum Mode
		{
			FULL,
			LIGHT
		}

		public enum ModuleType
		{
			FPS,
			RAM,
			AUDIO,
			ADVANCED
		}

		public enum ModuleState
		{
			FULL,
			TEXT,
			BASIC,
			BACKGROUND,
			OFF
		}

		public enum ModulePosition
		{
			TOP_RIGHT,
			TOP_LEFT,
			BOTTOM_RIGHT,
			BOTTOM_LEFT,
			FREE
		}

		public enum LookForAudioListener
		{
			ALWAYS,
			ON_SCENE_LOAD,
			NEVER
		}

		public enum ModulePreset
		{
			FPS_BASIC,
			FPS_TEXT,
			FPS_FULL,
			FPS_TEXT_RAM_TEXT,
			FPS_FULL_RAM_TEXT,
			FPS_FULL_RAM_FULL,
			FPS_TEXT_RAM_TEXT_AUDIO_TEXT,
			FPS_FULL_RAM_TEXT_AUDIO_TEXT,
			FPS_FULL_RAM_FULL_AUDIO_TEXT,
			FPS_FULL_RAM_FULL_AUDIO_FULL,
			FPS_FULL_RAM_FULL_AUDIO_FULL_ADVANCED_FULL,
			FPS_BASIC_ADVANCED_FULL
		}

		[SerializeField]
		private Mode m_graphyMode;

		[SerializeField]
		private bool m_enableOnStartup = true;

		[SerializeField]
		private bool m_keepAlive = true;

		[SerializeField]
		private bool m_background = true;

		[SerializeField]
		private Color m_backgroundColor = new Color(0f, 0f, 0f, 0.3f);

		[SerializeField]
		private bool m_enableHotkeys = true;

		[SerializeField]
		private KeyCode m_toggleModeKeyCode = KeyCode.G;

		[SerializeField]
		private bool m_toggleModeCtrl = true;

		[SerializeField]
		private bool m_toggleModeAlt;

		[SerializeField]
		private KeyCode m_toggleActiveKeyCode = KeyCode.H;

		[SerializeField]
		private bool m_toggleActiveCtrl = true;

		[SerializeField]
		private bool m_toggleActiveAlt;

		[SerializeField]
		private ModulePosition m_graphModulePosition;

		[SerializeField]
		private ModuleState m_fpsModuleState;

		[Range(0f, 200f)]
		[Tooltip("Time (in seconds) to reset the minimum and maximum framerates if they don't change in the specified time. Set to 0 if you don't want it to reset.")]
		[SerializeField]
		private int m_timeToResetMinMaxFps = 10;

		[SerializeField]
		private Color m_goodFpsColor = new Color32(118, 212, 58, byte.MaxValue);

		[SerializeField]
		private int m_goodFpsThreshold = 60;

		[SerializeField]
		private Color m_cautionFpsColor = new Color32(243, 232, 0, byte.MaxValue);

		[SerializeField]
		private int m_cautionFpsThreshold = 30;

		[SerializeField]
		private Color m_criticalFpsColor = new Color32(220, 41, 30, byte.MaxValue);

		[Range(10f, 300f)]
		[SerializeField]
		private int m_fpsGraphResolution = 150;

		[Range(1f, 200f)]
		[SerializeField]
		private int m_fpsTextUpdateRate = 3;

		[SerializeField]
		private ModuleState m_ramModuleState;

		[SerializeField]
		private Color m_allocatedRamColor = new Color32(byte.MaxValue, 190, 60, byte.MaxValue);

		[SerializeField]
		private Color m_reservedRamColor = new Color32(205, 84, 229, byte.MaxValue);

		[SerializeField]
		private Color m_monoRamColor = new Color(0.3f, 0.65f, 1f, 1f);

		[Range(10f, 300f)]
		[SerializeField]
		private int m_ramGraphResolution = 150;

		[Range(1f, 200f)]
		[SerializeField]
		private int m_ramTextUpdateRate = 3;

		[SerializeField]
		private ModuleState m_audioModuleState;

		[SerializeField]
		private LookForAudioListener m_findAudioListenerInCameraIfNull = LookForAudioListener.ON_SCENE_LOAD;

		[SerializeField]
		private AudioListener m_audioListener;

		[SerializeField]
		private Color m_audioGraphColor = Color.white;

		[Range(10f, 300f)]
		[SerializeField]
		private int m_audioGraphResolution = 81;

		[Range(1f, 200f)]
		[SerializeField]
		private int m_audioTextUpdateRate = 3;

		[SerializeField]
		private FFTWindow m_FFTWindow = FFTWindow.Blackman;

		[Tooltip("Must be a power of 2 and between 64-8192")]
		[SerializeField]
		private int m_spectrumSize = 512;

		[SerializeField]
		private ModulePosition m_advancedModulePosition = ModulePosition.BOTTOM_LEFT;

		[SerializeField]
		private ModuleState m_advancedModuleState;

		private bool m_initialized;

		private bool m_active = true;

		private bool m_focused = true;

		private G_FpsManager m_fpsManager;

		private G_RamManager m_ramManager;

		private G_AudioManager m_audioManager;

		private G_AdvancedData m_advancedData;

		private G_FpsMonitor m_fpsMonitor;

		private G_RamMonitor m_ramMonitor;

		private G_AudioMonitor m_audioMonitor;

		private ModulePreset m_modulePresetState = ModulePreset.FPS_BASIC_ADVANCED_FULL;

		public Mode GraphyMode
		{
			get
			{
				return m_graphyMode;
			}
			set
			{
				m_graphyMode = value;
				UpdateAllParameters();
			}
		}

		public bool EnableOnStartup => m_enableOnStartup;

		public bool KeepAlive => m_keepAlive;

		public bool Background
		{
			get
			{
				return m_background;
			}
			set
			{
				m_background = value;
				UpdateAllParameters();
			}
		}

		public Color BackgroundColor
		{
			get
			{
				return m_backgroundColor;
			}
			set
			{
				m_backgroundColor = value;
				UpdateAllParameters();
			}
		}

		public ModulePosition GraphModulePosition
		{
			get
			{
				return m_graphModulePosition;
			}
			set
			{
				m_graphModulePosition = value;
				m_fpsManager.SetPosition(m_graphModulePosition);
				m_ramManager.SetPosition(m_graphModulePosition);
				m_audioManager.SetPosition(m_graphModulePosition);
			}
		}

		public ModuleState FpsModuleState
		{
			get
			{
				return m_fpsModuleState;
			}
			set
			{
				m_fpsModuleState = value;
				m_fpsManager.SetState(m_fpsModuleState);
			}
		}

		public int TimeToResetMinMaxFps
		{
			get
			{
				return m_timeToResetMinMaxFps;
			}
			set
			{
				m_timeToResetMinMaxFps = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public Color GoodFPSColor
		{
			get
			{
				return m_goodFpsColor;
			}
			set
			{
				m_goodFpsColor = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public Color CautionFPSColor
		{
			get
			{
				return m_cautionFpsColor;
			}
			set
			{
				m_cautionFpsColor = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public Color CriticalFPSColor
		{
			get
			{
				return m_criticalFpsColor;
			}
			set
			{
				m_criticalFpsColor = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public int GoodFPSThreshold
		{
			get
			{
				return m_goodFpsThreshold;
			}
			set
			{
				m_goodFpsThreshold = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public int CautionFPSThreshold
		{
			get
			{
				return m_cautionFpsThreshold;
			}
			set
			{
				m_cautionFpsThreshold = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public int FpsGraphResolution
		{
			get
			{
				return m_fpsGraphResolution;
			}
			set
			{
				m_fpsGraphResolution = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public int FpsTextUpdateRate
		{
			get
			{
				return m_fpsTextUpdateRate;
			}
			set
			{
				m_fpsTextUpdateRate = value;
				m_fpsManager.UpdateParameters();
			}
		}

		public float CurrentFPS => m_fpsMonitor.CurrentFPS;

		public float AverageFPS => m_fpsMonitor.AverageFPS;

		public float MinFPS => m_fpsMonitor.MinFPS;

		public float MaxFPS => m_fpsMonitor.MaxFPS;

		public ModuleState RamModuleState
		{
			get
			{
				return m_ramModuleState;
			}
			set
			{
				m_ramModuleState = value;
				m_ramManager.SetState(m_ramModuleState);
			}
		}

		public Color AllocatedRamColor
		{
			get
			{
				return m_allocatedRamColor;
			}
			set
			{
				m_allocatedRamColor = value;
				m_ramManager.UpdateParameters();
			}
		}

		public Color ReservedRamColor
		{
			get
			{
				return m_reservedRamColor;
			}
			set
			{
				m_reservedRamColor = value;
				m_ramManager.UpdateParameters();
			}
		}

		public Color MonoRamColor
		{
			get
			{
				return m_monoRamColor;
			}
			set
			{
				m_monoRamColor = value;
				m_ramManager.UpdateParameters();
			}
		}

		public int RamGraphResolution
		{
			get
			{
				return m_ramGraphResolution;
			}
			set
			{
				m_ramGraphResolution = value;
				m_ramManager.UpdateParameters();
			}
		}

		public int RamTextUpdateRate
		{
			get
			{
				return m_ramTextUpdateRate;
			}
			set
			{
				m_ramTextUpdateRate = value;
				m_ramManager.UpdateParameters();
			}
		}

		public float AllocatedRam => m_ramMonitor.AllocatedRam;

		public float ReservedRam => m_ramMonitor.ReservedRam;

		public float MonoRam => m_ramMonitor.MonoRam;

		public ModuleState AudioModuleState
		{
			get
			{
				return m_audioModuleState;
			}
			set
			{
				m_audioModuleState = value;
				m_audioManager.SetState(m_audioModuleState);
			}
		}

		public AudioListener AudioListener
		{
			get
			{
				return m_audioListener;
			}
			set
			{
				m_audioListener = value;
				m_audioManager.UpdateParameters();
			}
		}

		public LookForAudioListener FindAudioListenerInCameraIfNull
		{
			get
			{
				return m_findAudioListenerInCameraIfNull;
			}
			set
			{
				m_findAudioListenerInCameraIfNull = value;
				m_audioManager.UpdateParameters();
			}
		}

		public Color AudioGraphColor
		{
			get
			{
				return m_audioGraphColor;
			}
			set
			{
				m_audioGraphColor = value;
				m_audioManager.UpdateParameters();
			}
		}

		public int AudioGraphResolution
		{
			get
			{
				return m_audioGraphResolution;
			}
			set
			{
				m_audioGraphResolution = value;
				m_audioManager.UpdateParameters();
			}
		}

		public int AudioTextUpdateRate
		{
			get
			{
				return m_audioTextUpdateRate;
			}
			set
			{
				m_audioTextUpdateRate = value;
				m_audioManager.UpdateParameters();
			}
		}

		public FFTWindow FftWindow
		{
			get
			{
				return m_FFTWindow;
			}
			set
			{
				m_FFTWindow = value;
				m_audioManager.UpdateParameters();
			}
		}

		public int SpectrumSize
		{
			get
			{
				return m_spectrumSize;
			}
			set
			{
				m_spectrumSize = value;
				m_audioManager.UpdateParameters();
			}
		}

		public float[] Spectrum => m_audioMonitor.Spectrum;

		public float MaxDB => m_audioMonitor.MaxDB;

		public ModuleState AdvancedModuleState
		{
			get
			{
				return m_advancedModuleState;
			}
			set
			{
				m_advancedModuleState = value;
				m_advancedData.SetState(m_advancedModuleState);
			}
		}

		public ModulePosition AdvancedModulePosition
		{
			get
			{
				return m_advancedModulePosition;
			}
			set
			{
				m_advancedModulePosition = value;
				m_advancedData.SetPosition(m_advancedModulePosition);
			}
		}

		protected GraphyManager()
		{
		}

		private void Start()
		{
			Init();
		}

		private void Update()
		{
			if (m_focused && m_enableHotkeys)
			{
				CheckForHotkeyPresses();
			}
		}

		private void OnApplicationFocus(bool isFocused)
		{
			m_focused = isFocused;
			if (m_initialized && isFocused)
			{
				RefreshAllParameters();
			}
		}

		public void SetModulePosition(ModuleType moduleType, ModulePosition modulePosition)
		{
			switch (moduleType)
			{
			case ModuleType.FPS:
			case ModuleType.RAM:
			case ModuleType.AUDIO:
				m_graphModulePosition = modulePosition;
				m_ramManager.SetPosition(modulePosition);
				m_fpsManager.SetPosition(modulePosition);
				m_audioManager.SetPosition(modulePosition);
				break;
			case ModuleType.ADVANCED:
				m_advancedData.SetPosition(modulePosition);
				break;
			}
		}

		public void SetModuleMode(ModuleType moduleType, ModuleState moduleState)
		{
			switch (moduleType)
			{
			case ModuleType.FPS:
				m_fpsManager.SetState(moduleState);
				break;
			case ModuleType.RAM:
				m_ramManager.SetState(moduleState);
				break;
			case ModuleType.AUDIO:
				m_audioManager.SetState(moduleState);
				break;
			case ModuleType.ADVANCED:
				m_advancedData.SetState(moduleState);
				break;
			}
		}

		public void ToggleModes()
		{
			if ((int)m_modulePresetState >= Enum.GetNames(typeof(ModulePreset)).Length - 1)
			{
				m_modulePresetState = ModulePreset.FPS_BASIC;
			}
			else
			{
				m_modulePresetState++;
			}
			SetPreset(m_modulePresetState);
		}

		public void SetPreset(ModulePreset modulePreset)
		{
			m_modulePresetState = modulePreset;
			switch (m_modulePresetState)
			{
			case ModulePreset.FPS_BASIC:
				m_fpsManager.SetState(ModuleState.BASIC);
				m_ramManager.SetState(ModuleState.OFF);
				m_audioManager.SetState(ModuleState.OFF);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_TEXT:
				m_fpsManager.SetState(ModuleState.TEXT);
				m_ramManager.SetState(ModuleState.OFF);
				m_audioManager.SetState(ModuleState.OFF);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_FULL:
				m_fpsManager.SetState(ModuleState.FULL);
				m_ramManager.SetState(ModuleState.OFF);
				m_audioManager.SetState(ModuleState.OFF);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_TEXT_RAM_TEXT:
				m_fpsManager.SetState(ModuleState.TEXT);
				m_ramManager.SetState(ModuleState.TEXT);
				m_audioManager.SetState(ModuleState.OFF);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_FULL_RAM_TEXT:
				m_fpsManager.SetState(ModuleState.FULL);
				m_ramManager.SetState(ModuleState.TEXT);
				m_audioManager.SetState(ModuleState.OFF);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_FULL_RAM_FULL:
				m_fpsManager.SetState(ModuleState.FULL);
				m_ramManager.SetState(ModuleState.FULL);
				m_audioManager.SetState(ModuleState.OFF);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_TEXT_RAM_TEXT_AUDIO_TEXT:
				m_fpsManager.SetState(ModuleState.TEXT);
				m_ramManager.SetState(ModuleState.TEXT);
				m_audioManager.SetState(ModuleState.TEXT);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_FULL_RAM_TEXT_AUDIO_TEXT:
				m_fpsManager.SetState(ModuleState.FULL);
				m_ramManager.SetState(ModuleState.TEXT);
				m_audioManager.SetState(ModuleState.TEXT);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_FULL_RAM_FULL_AUDIO_TEXT:
				m_fpsManager.SetState(ModuleState.FULL);
				m_ramManager.SetState(ModuleState.FULL);
				m_audioManager.SetState(ModuleState.TEXT);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_FULL_RAM_FULL_AUDIO_FULL:
				m_fpsManager.SetState(ModuleState.FULL);
				m_ramManager.SetState(ModuleState.FULL);
				m_audioManager.SetState(ModuleState.FULL);
				m_advancedData.SetState(ModuleState.OFF);
				break;
			case ModulePreset.FPS_FULL_RAM_FULL_AUDIO_FULL_ADVANCED_FULL:
				m_fpsManager.SetState(ModuleState.FULL);
				m_ramManager.SetState(ModuleState.FULL);
				m_audioManager.SetState(ModuleState.FULL);
				m_advancedData.SetState(ModuleState.FULL);
				break;
			case ModulePreset.FPS_BASIC_ADVANCED_FULL:
				m_fpsManager.SetState(ModuleState.BASIC);
				m_ramManager.SetState(ModuleState.OFF);
				m_audioManager.SetState(ModuleState.OFF);
				m_advancedData.SetState(ModuleState.FULL);
				break;
			}
		}

		public void ToggleActive()
		{
			if (!m_active)
			{
				Enable();
			}
			else
			{
				Disable();
			}
		}

		public void Enable()
		{
			m_fpsManager.RestorePreviousState();
			m_ramManager.RestorePreviousState();
			m_audioManager.RestorePreviousState();
			m_advancedData.RestorePreviousState();
			m_active = true;
		}

		public void Disable()
		{
			m_fpsManager.SetState(ModuleState.OFF);
			m_ramManager.SetState(ModuleState.OFF);
			m_audioManager.SetState(ModuleState.OFF);
			m_advancedData.SetState(ModuleState.OFF);
			m_active = false;
		}

		private void Init()
		{
			if (m_keepAlive)
			{
				UnityEngine.Object.DontDestroyOnLoad(base.transform.root.gameObject);
			}
			m_fpsMonitor = (GetComponentInChildren(typeof(G_FpsMonitor), includeInactive: true) as G_FpsMonitor);
			m_ramMonitor = (GetComponentInChildren(typeof(G_RamMonitor), includeInactive: true) as G_RamMonitor);
			m_audioMonitor = (GetComponentInChildren(typeof(G_AudioMonitor), includeInactive: true) as G_AudioMonitor);
			m_fpsManager = (GetComponentInChildren(typeof(G_FpsManager), includeInactive: true) as G_FpsManager);
			m_ramManager = (GetComponentInChildren(typeof(G_RamManager), includeInactive: true) as G_RamManager);
			m_audioManager = (GetComponentInChildren(typeof(G_AudioManager), includeInactive: true) as G_AudioManager);
			m_advancedData = (GetComponentInChildren(typeof(G_AdvancedData), includeInactive: true) as G_AdvancedData);
			m_fpsManager.SetPosition(m_graphModulePosition);
			m_ramManager.SetPosition(m_graphModulePosition);
			m_audioManager.SetPosition(m_graphModulePosition);
			m_advancedData.SetPosition(m_advancedModulePosition);
			m_fpsManager.SetState(m_fpsModuleState);
			m_ramManager.SetState(m_ramModuleState);
			m_audioManager.SetState(m_audioModuleState);
			m_advancedData.SetState(m_advancedModuleState);
			if (!m_enableOnStartup)
			{
				ToggleActive();
			}
			m_initialized = true;
		}

		private void CheckForHotkeyPresses()
		{
			if (m_toggleModeCtrl && m_toggleModeAlt)
			{
				if (CheckFor3KeyPress(m_toggleModeKeyCode, KeyCode.LeftControl, KeyCode.LeftAlt) || CheckFor3KeyPress(m_toggleModeKeyCode, KeyCode.RightControl, KeyCode.LeftAlt) || CheckFor3KeyPress(m_toggleModeKeyCode, KeyCode.RightControl, KeyCode.RightAlt) || CheckFor3KeyPress(m_toggleModeKeyCode, KeyCode.LeftControl, KeyCode.RightAlt))
				{
					ToggleModes();
				}
			}
			else if (m_toggleModeCtrl)
			{
				if (CheckFor2KeyPress(m_toggleModeKeyCode, KeyCode.LeftControl) || CheckFor2KeyPress(m_toggleModeKeyCode, KeyCode.RightControl))
				{
					ToggleModes();
				}
			}
			else if (m_toggleModeAlt)
			{
				if (CheckFor2KeyPress(m_toggleModeKeyCode, KeyCode.LeftAlt) || CheckFor2KeyPress(m_toggleModeKeyCode, KeyCode.RightAlt))
				{
					ToggleModes();
				}
			}
			else if (CheckFor1KeyPress(m_toggleModeKeyCode))
			{
				ToggleModes();
			}
			if (m_toggleActiveCtrl && m_toggleActiveAlt)
			{
				if (CheckFor3KeyPress(m_toggleActiveKeyCode, KeyCode.LeftControl, KeyCode.LeftAlt) || CheckFor3KeyPress(m_toggleActiveKeyCode, KeyCode.RightControl, KeyCode.LeftAlt) || CheckFor3KeyPress(m_toggleActiveKeyCode, KeyCode.RightControl, KeyCode.RightAlt) || CheckFor3KeyPress(m_toggleActiveKeyCode, KeyCode.LeftControl, KeyCode.RightAlt))
				{
					ToggleActive();
				}
			}
			else if (m_toggleActiveCtrl)
			{
				if (CheckFor2KeyPress(m_toggleActiveKeyCode, KeyCode.LeftControl) || CheckFor2KeyPress(m_toggleActiveKeyCode, KeyCode.RightControl))
				{
					ToggleActive();
				}
			}
			else if (m_toggleActiveAlt)
			{
				if (CheckFor2KeyPress(m_toggleActiveKeyCode, KeyCode.LeftAlt) || CheckFor2KeyPress(m_toggleActiveKeyCode, KeyCode.RightAlt))
				{
					ToggleActive();
				}
			}
			else if (CheckFor1KeyPress(m_toggleActiveKeyCode))
			{
				ToggleActive();
			}
		}

		private bool CheckFor1KeyPress(KeyCode key)
		{
			return UnityEngine.Input.GetKeyDown(key);
		}

		private bool CheckFor2KeyPress(KeyCode key1, KeyCode key2)
		{
			return (UnityEngine.Input.GetKeyDown(key1) && UnityEngine.Input.GetKey(key2)) || (UnityEngine.Input.GetKeyDown(key2) && UnityEngine.Input.GetKey(key1));
		}

		private bool CheckFor3KeyPress(KeyCode key1, KeyCode key2, KeyCode key3)
		{
			return (UnityEngine.Input.GetKeyDown(key1) && UnityEngine.Input.GetKey(key2) && UnityEngine.Input.GetKey(key3)) || (UnityEngine.Input.GetKeyDown(key2) && UnityEngine.Input.GetKey(key1) && UnityEngine.Input.GetKey(key3)) || (UnityEngine.Input.GetKeyDown(key3) && UnityEngine.Input.GetKey(key1) && UnityEngine.Input.GetKey(key2));
		}

		private void UpdateAllParameters()
		{
			m_fpsManager.UpdateParameters();
			m_ramManager.UpdateParameters();
			m_audioManager.UpdateParameters();
			m_advancedData.UpdateParameters();
		}

		private void RefreshAllParameters()
		{
			m_fpsManager.RefreshParameters();
			m_ramManager.RefreshParameters();
			m_audioManager.RefreshParameters();
			m_advancedData.RefreshParameters();
		}
	}
}
